import React, { useState, useEffect, useContext } from "react";
import { ConfigProvider } from "antd";
import classNames from "classnames";
import PropTypes from "prop-types";
/**
 * 返回当前显示设备的物理像素分辨率与CSS像素分辨率之比
 *
 * @param context
 * @see api 有些废弃了，其实类型 CanvasRenderingContext2D
 */
const getPixelRatio = (context) => {
  if (!context) {
    return 1;
  }
  const backingStore =
    context.backingStorePixelRatio ||
    context.webkitBackingStorePixelRatio ||
    context.mozBackingStorePixelRatio ||
    context.msBackingStorePixelRatio ||
    context.oBackingStorePixelRatio ||
    context.backingStorePixelRatio ||
    1;
  return (window.devicePixelRatio || 1) / backingStore;
};

const WaterMark = (props) => {
  const {
    children,
    style,
    className,
    markStyle,
    markClassName,
    // antd 内容层 zIndex 基本上在 10 以下 https://github.com/ant-design/ant-design/blob/6192403b2ce517c017f9e58a32d58774921c10cd/components/style/themes/default.less#L335
    zIndex = 9,
    gapX = 212,
    gapY = 222,
    width = 120,
    height = 64,
    rotate = -22, // 默认旋转 -22 度
    image,
    content,
    offsetLeft,
    offsetTop,
    fontStyle = "normal",
    fontWeight = "normal",
    fontColor = "rgba(0,0,0,.15)",
    fontSize = 16,
    fontFamily = "sans-serif",
    prefixCls: customizePrefixCls,
  } = props;

  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls("pro-layout-watermark", customizePrefixCls);
  const wrapperCls = classNames(`${prefixCls}-wrapper`, className);
  const waterMakrCls = classNames(prefixCls, markClassName);
  const [base64Url, setBase64Url] = useState("");

  useEffect(() => {
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    const ratio = getPixelRatio(ctx);

    const canvasWidth = `${(gapX + width) * ratio}px`;
    const canvasHeight = `${(gapY + height) * ratio}px`;
    const canvasOffsetLeft = offsetLeft || gapX / 2;
    const canvasOffsetTop = offsetTop || gapY / 2;

    canvas.setAttribute("width", canvasWidth);
    canvas.setAttribute("height", canvasHeight);

    if (ctx) {
      // 旋转字符 rotate
      ctx.translate(canvasOffsetLeft * ratio, canvasOffsetTop * ratio);
      ctx.rotate((Math.PI / 180) * Number(rotate));
      const markWidth = width * ratio;
      const markHeight = height * ratio;

      if (image) {
        const img = new Image();
        img.crossOrigin = "anonymous";
        img.referrerPolicy = "no-referrer";
        img.src = image;
        img.onload = () => {
          ctx.drawImage(img, 0, 0, markWidth, markHeight);
          setBase64Url(canvas.toDataURL());
        };
      } else if (content) {
        const markSize = Number(fontSize) * ratio;
        ctx.font = `${fontStyle} normal ${fontWeight} ${markSize}px/${markHeight}px ${fontFamily}`;
        ctx.fillStyle = fontColor;
        ctx.fillText(content, 0, 0);
        setBase64Url(canvas.toDataURL());
      }
    } else {
      // eslint-disable-next-line no-console
      console.error("当前环境不支持Canvas");
    }
  }, [
    gapX,
    gapY,
    offsetLeft,
    offsetTop,
    rotate,
    fontStyle,
    fontWeight,
    width,
    height,
    fontFamily,
    fontColor,
    image,
    content,
    fontSize,
  ]);

  return (
    <div
      style={{
        position: "relative",
        ...style,
      }}
      className={wrapperCls}
    >
      {children}
      <div
        className={waterMakrCls}
        style={{
          zIndex,
          position: "absolute",
          left: 0,
          top: 0,
          width: "100%",
          height: "100%",
          backgroundSize: `${gapX + width}px`,
          pointerEvents: "none",
          backgroundRepeat: "repeat",
          backgroundImage: `url('${base64Url}')`,
          ...markStyle,
        }}
      />
    </div>
  );
};

WaterMark.propTypes = {
  className: PropTypes.string,
  style: PropTypes.object,
  markStyle: PropTypes.object,
  markClassName: PropTypes.string,
  gapX: PropTypes.number,
  gapY: PropTypes.number,
  width: PropTypes.number,
  height: PropTypes.number,
  rotate: PropTypes.number,
  image: PropTypes.string,
  content: PropTypes.string,
  offsetLeft: PropTypes.number,
  offsetTop: PropTypes.number,
  fontStyle: PropTypes.string,
  fontWeight: PropTypes.string,
  fontColor: PropTypes.string,
  fontSize: PropTypes.number,
  fontFamily: PropTypes.string,
  prefixCls: PropTypes.string,
  zIndex: PropTypes.number,
};

WaterMark.defaultProps = {
  className: "",
  style: {},
  markStyle: {},
  markClassName: "",
  gapX: 212,
  gapY: 222,
  width: 120,
  height: 64,
  rotate: -22,
  image: "",
  content: "",
  offsetLeft: 0,
  offsetTop: 0,
  fontStyle: "normal",
  fontWeight: "normal",
  fontColor: "rgba(0,0,0,.15)",
  fontSize: 16,
  fontFamily: "sans-serif",
  prefixCls: "",
  zIndex: 9,
};

export default WaterMark;
